// ignore_for_file: prefer_null_aware_operators, library_private_types_in_public_api

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:syncfusion_flutter_charts/charts.dart';

class ChartWidgetData {
  /// 图表事例名称
  final String? name;

  /// 图表数据颜色
  final Color color;

  /// 0柱状图，1折线图，2虚线图，3覆盖柱状图，4折线图-尖角
  final int type;

  /// 0是左轴，1是右轴
  final int yAxis;

  /// X轴数据key
  final String xKey;

  /// Y轴数据key
  final String yKey;

  /// 是否有原点
  final bool isMarker;

  /// 原点大小
  final double markerSize;

  ChartWidgetData({
    this.name,
    required this.color,
    required this.type,
    this.yAxis = 0,
    required this.xKey,
    required this.yKey,
    this.isMarker = false,
    this.markerSize = 2,
  });
}

class ChartWidget extends StatefulWidget {
  /// 图表数据
  final List dataList;

  /// 图表配置数据
  final List<ChartWidgetData> widgetList;

  /// 图表高度 默认150.w
  final double? chartHeight;

  /// 左轴最小值
  final double? leftMinimum;

  /// 左轴最大值
  final double? leftMaximum;

  /// 左轴间隔值
  final double? leftInterval;

  /// 右轴最小值
  final double? rightMinimum;

  /// 右轴最大值
  final double? rightMaximum;

  /// 右轴间隔值
  final double? rightInterval;

  /// 左轴名称
  final String? leftYAxisName;

  /// 右轴名称
  final String? rightYAxisName;

  /// 图表底部文字
  final String? chartBottomText;

  /// X轴文字旋转角度
  final int? chartXTextRotation;

  /// X轴文字样式
  final TextStyle? xTextStyle;

  /// X轴最大刻度
  final int? xMaximum;

  // 左轴刻度格式化
  final String Function(num value)? leftFormatterText;

  // 右轴刻度格式化
  final String Function(num value)? rightFormatterText;

  // 左轴最大Labels
  final int? leftMaximumLabels;

  // 右轴最大Labels
  final int? rightMaximumLabels;

  const ChartWidget(
    this.dataList,
    this.widgetList, {
    Key? key,
    this.chartHeight,
    this.leftMinimum,
    this.leftMaximum,
    this.leftInterval,
    this.rightMinimum,
    this.rightMaximum,
    this.rightInterval,
    this.leftYAxisName,
    this.rightYAxisName,
    this.chartBottomText,
    this.chartXTextRotation,
    this.xTextStyle,
    this.xMaximum,
    this.leftFormatterText,
    this.rightFormatterText,
    this.leftMaximumLabels,
    this.rightMaximumLabels,
  }) : super(key: key);

  @override
  _ChartWidgetState createState() => _ChartWidgetState();
}

class _ChartWidgetState extends State<ChartWidget> {
  @override
  void initState() {
    super.initState();
    initData();
  }

  initData() async {}

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Wrap(
          children: buildTag(),
        ),
        (widget.leftYAxisName == null && widget.rightYAxisName == null)
            ? Container()
            : Container(
                margin: EdgeInsets.symmetric(horizontal: 10.w, vertical: 5.w),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Text(
                      widget.leftYAxisName ?? '',
                      style: TextStyle(fontSize: 12.sp),
                    ),
                    Text(
                      widget.rightYAxisName ?? '',
                      style: TextStyle(fontSize: 12.sp),
                    )
                  ],
                ),
              ),
        SizedBox(
          height: widget.chartHeight ?? 150.w,
          child: SfCartesianChart(
            primaryXAxis: CategoryAxis(
                labelStyle: widget.xTextStyle,
                labelRotation: widget.chartXTextRotation ?? 0,
                isVisible: widget.chartBottomText == null,
                maximumLabels: widget.xMaximum ?? 0),
            primaryYAxis: const CategoryAxis(isVisible: false),
            // 双轴
            axes: [
              NumericAxis(
                  name: 'left',
                  opposedPosition: false,
                  axisLabelFormatter: widget.leftFormatterText == null
                      ? null
                      : (AxisLabelRenderDetails details) => ChartAxisLabel(
                          widget.leftFormatterText!(details.value),
                          details.textStyle),
                  minimum: widget.leftMinimum,
                  maximum: widget.leftMaximum,
                  maximumLabels: widget.leftMaximumLabels ?? 0,
                  interval: widget.leftInterval),
              if (widget.rightYAxisName != null)
                NumericAxis(
                    name: 'right',
                    opposedPosition: true,
                    axisLabelFormatter: widget.rightFormatterText == null
                        ? null
                        : (AxisLabelRenderDetails details) => ChartAxisLabel(
                            widget.rightFormatterText!(details.value),
                            details.textStyle),
                    minimum: widget.rightMinimum,
                    maximum: widget.rightMaximum,
                    maximumLabels: widget.rightMaximumLabels ?? 0,
                    interval: widget.rightInterval),
            ],
            legend:
                const Legend(isVisible: false, position: LegendPosition.top),
            series: buildSeries(),
          ),
        ),
        Container(
          alignment: Alignment.center,
          child: Text(
            widget.chartBottomText ?? '',
            style: TextStyle(fontSize: 12.sp),
          ),
        ),
      ],
    );
  }

  ///跟据formType构建图表，参考上方标题
  List<CartesianSeries> buildSeries() {
    List<CartesianSeries> result = [];
    for (ChartWidgetData item in widget.widgetList) {
      if (item.type == 0) {
        result.add(ColumnSeries<dynamic, String>(
          yAxisName: item.yAxis == 0 ? 'left' : 'right',
          isVisibleInLegend: false,
          width: widget.widgetList.length < 10 ? 0.1 : 0,
          color: item.color,
          legendItemText: '',
          dataSource: widget.dataList,
          xValueMapper: (dynamic sales, _) =>
              sales[item.xKey] == null ? null : sales[item.xKey].toString(),
          yValueMapper: (dynamic sales, _) => yValueMapperMake(sales, item),
          markerSettings: MarkerSettings(
              isVisible: item.isMarker,
              width: item.markerSize,
              height: item.markerSize), //修饰数据点(显示圆圈)
        ));
      }
      if (item.type == 1) {
        result.add(SplineSeries<dynamic, String>(
          yAxisName: item.yAxis == 0 ? 'left' : 'right',
          isVisibleInLegend: false,
          color: item.color,
          legendItemText: '',
          dataSource: widget.dataList,
          xValueMapper: (dynamic sales, _) =>
              sales[item.xKey] == null ? null : sales[item.xKey].toString(),
          yValueMapper: (dynamic sales, _) => yValueMapperMake(sales, item),
          markerSettings: MarkerSettings(
              isVisible: item.isMarker,
              width: item.markerSize,
              height: item.markerSize), //修饰数据点(显示圆圈)
        ));
      }

      if (item.type == 2 || item.type == 4) {
        result.add(LineSeries<dynamic, String>(
          dashArray: item.type == 2 ? [10, 10] : null,
          yAxisName: item.yAxis == 0 ? 'left' : 'right',
          isVisibleInLegend: false,
          color: item.color,
          legendItemText: '',
          dataSource: widget.dataList,
          xValueMapper: (dynamic sales, _) =>
              sales[item.xKey] == null ? null : sales[item.xKey].toString(),
          yValueMapper: (dynamic sales, _) => yValueMapperMake(sales, item),
          markerSettings: MarkerSettings(
              isVisible: item.isMarker,
              width: item.markerSize,
              height: item.markerSize), //修饰数据点(显示圆圈)
        ));
      }

      if (item.type == 3) {
        result.add(StackedColumnSeries<dynamic, String>(
          yAxisName: item.yAxis == 0 ? 'left' : 'right',
          isVisibleInLegend: false,
          width: widget.widgetList.length < 10 ? 0.1 : 0,
          color: item.color,
          legendItemText: '',
          dataSource: widget.dataList,
          xValueMapper: (dynamic sales, _) =>
              sales[item.xKey] == null ? null : sales[item.xKey].toString(),
          yValueMapper: (dynamic sales, _) => yValueMapperMake(sales, item),
          markerSettings: MarkerSettings(
              isVisible: item.isMarker,
              width: item.markerSize,
              height: item.markerSize), //修饰数据点(显示圆圈)
        ));
      }
    }
    return result;
  }

  /// Y轴数据处理
  num? yValueMapperMake(dynamic sales, ChartWidgetData item) {
    String tempY = '${sales[item.yKey]}';
    if (tempY != 'null' && tempY.isNotEmpty) {
      return double.parse('${sales[item.yKey]}');
    }
    return null;
  }

  /// 构建图表上方图例
  List<Widget> buildTag() {
    List<Widget> result = [];
    for (ChartWidgetData item in widget.widgetList) {
      if (item.name != null) {
        result.add(Container(
          margin: EdgeInsets.symmetric(horizontal: 10.w),
          child: Row(
            mainAxisSize: MainAxisSize.min,
            children: [
              tagMake(item),
              Text(item.name ?? '', style: TextStyle(fontSize: 14.w)),
            ],
          ),
        ));
      }
    }
    return result;
  }

  /// 图表事例
  Widget tagMake(ChartWidgetData item) {
    if (item.type == 0 || item.type == 3) {
      return Container(
          margin: EdgeInsets.only(right: 10.w),
          width: 5.w,
          height: 12.w,
          color: item.color);
    }
    if (item.type == 1 || item.type == 2 || item.type == 4) {
      return Container(
          margin: EdgeInsets.only(right: 10.w),
          width: 12.w,
          height: 3.w,
          color: item.color);
    }
    return Container();
  }
}
